﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Web.UI;
using System.Collections.ObjectModel;
using System.Reflection;
using ValidationLibrary;

namespace WebFormsBinder
{
    public class Binder<TEntity>
    {
        List<AbstractBinding<TEntity>> _bindings { get; set;}
        public IEnumerable<AbstractBinding<TEntity>> Bindings { get { return _bindings.AsReadOnly(); } }

        IClientEngine<TEntity> _clientEngine { get; set; }
        IClientEngine<TEntity> GetClientEngine()
        {
            if (_clientEngine != null)
                return _clientEngine;
            return new JQueryClientEngine<TEntity>();
        }

        public Binder()
        {
            _bindings = new List<AbstractBinding<TEntity>>();
        }

        public Binding<TEntity, TProperty, TControl> Bind<TProperty, TControl>(Expression<Func<TEntity, TProperty>> property, TControl control)
        {
            var binding = new Binding<TEntity, TProperty, TControl>(property, control);
            _bindings.Add(binding);
            return binding;
        }

        public void ToForm(TEntity entity)
        {
            foreach (AbstractBinding<TEntity> binding in _bindings)
                binding.ToForm(entity);
        }

        public void ToEntity(TEntity entity)
        {
            foreach (AbstractBinding<TEntity> binding in _bindings)
                binding.ToEntity(entity);
        }

        public void RegisterJavascript(ClientScriptManager clientScriptManager, TEntity entity)
        {
            IClientEngine<TEntity> engine = GetClientEngine();
            JSGenerator<TEntity> jsGenerator = null;

            IValidatable<TEntity> validatableEntity = entity as IValidatable<TEntity>;
            if (validatableEntity != null)
            {
                ModelValidator<TEntity> validator = validatableEntity.ModelValidator;
                jsGenerator = new JSGenerator<TEntity>(validator, this, entity);
                engine.RegisterJavascript(clientScriptManager, Bindings, jsGenerator);
            }
            else
            {
                engine.RegisterJavascript(clientScriptManager, Bindings);
            }
        }
    }
}
